package com.mspbots.ticketai.graderule;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.mspbots.ticketai.GradeRuleInterceptorAdapter;
import com.mspbots.ticketai.model.Ticket;
import com.mspbots.ticketai.model.TicketRule;
import lombok.Data;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author Jay.Yang
 */
@Service(value = "IN_PROCESS_STATUS_POINT_RULE")
public class InProcessStatusRuleInterceptor extends GradeRuleInterceptorAdapter {

    private List<InProcessStatusParam> params;

    @Override
    public void prepare(TicketRule rule) {
        params = this.objectMapper.convertValue(rule.getParams(), new TypeReference<>() {
        });
    }

    @Override
    public void process(Ticket ticket) {
        AtomicInteger order = new AtomicInteger();
        if (!StringUtils.isEmpty(ticket.getUpdatedBy()) && !StringUtils.isEmpty(ticket.getIdentifier())) {
            params.stream().filter(item -> item.isSelected() && item.getStatusIds().contains(ticket.getStatusId()))
                    .forEach(item -> {
                        if (ticket.getIdentifier().equalsIgnoreCase(ticket.getUpdatedBy()) && !ObjectUtils.isEmpty(item.getActiveUserpoints())) {
                            order.addAndGet(item.getActiveUserpoints());
                        } else if (!ObjectUtils.isEmpty(item.getOtherUserPoints())) {
                            int points = item.getOtherUserPoints();
                            if (points > 0) {
                                points = -1 * points;
                            }
                            order.addAndGet(points);
                        }
                    });
        }
        ObjectNode itemsNode = this.objectMapper.createObjectNode();
        itemsNode.put("updatedBy", ticket.getUpdatedBy());
        itemsNode.put("status", ticket.getStatus());
        itemsNode.put("point", order.get());
        ObjectNode orderDetailNode = ticket.getOrderDetail() == null ? this.objectMapper.createObjectNode() : ticket.getOrderDetail().deepCopy();
        orderDetailNode.set("InProcessStatus", itemsNode);
        ticket.setOrderDetail(orderDetailNode);
        ticket.setOrder(ticket.getOrder() + order.get());
    }

    @Data
    private static class InProcessStatusParam {
        private Integer index;
        private Integer activeUserpoints;
        private Integer otherUserPoints;
        private List<Integer> statusIds;
        private boolean selected;
    }
}
